package com.can.pool;

import java.util.concurrent.*;

//Executors不安全，所以要自定义new ThreadPoolExecutor
//自定义线程池
//new ThreadPoolExecutor.AbortPolicy()); //队列满了，还有人进来，不处理这个人的，抛出异常
//new ThreadPoolExecutor.DiscardPolicy()); //队列满了，还有人进来，不处理这个人的，不会抛出异常
//new ThreadPoolExecutor.DiscardOldestPolicy()); //队列满了，尝试去和最早的线程竞争，不会抛出异常
//new ThreadPoolExecutor.CallerRunsPolicy()); //队列满了，哪来的去哪里！打发  这里是main线程去处理

public class ThreadPoolExecutor02 {
    public static void main(String[] args) {
        //- corePoolSize：核心线程池大小
        //- maximumPoolSize：最大核心线程池大小
        //- keepAliveTime：最大线程池的大小,超时了没有人调用就会释放
        //- unit：超时单位
        //- workQueue：阻塞队列,等候区满了，使用最大线程池
        //- threadFactory：线程工厂，创建线程的，一般不用动
        //- handler：拒绝策略
        System.out.println(Runtime.getRuntime().availableProcessors());//获取CPU核数
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,
                //最大线程到底该如何定义
                //1.CPU 密集型，几核，就是几，可以保证CPU的效率最高！
                //2.IO 密集型  >判断你程序中十分耗IO的线程，
                //程序 15个大型任务 io十分占用资源
                5, //8
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()); //队列满了，尝试去和最早的竞争，不会抛出异常


        try {
            //最大承载：Queue + max
            //超过 RejectedExecutionException
            for (int i = 0; i < 8; i++) {
                //使用了线程池之后，要使用线程池来创建线程
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" OK");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //线程池用完，程序结束，关闭线程池
            threadPool.shutdown();
        }
    }
}
